﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Web.UI.WebControls;
using Elkitools.EditorParts.ListSelector.Tools;

namespace Elkitools.EditorParts.ListSelector.Controls
{
    [Serializable]
    internal class CalendarViewModel
    {
        //-----------------------------------------------------------------
        #region Properties
        //-----------------------------------------------------------------

        //internal CalendarsWebsAndLists View { get; set; }

        internal CalendarModel Model { get; set; }

        //-----------------------------------------------------------------
        #endregion Properties
        //-----------------------------------------------------------------

        //-----------------------------------------------------------------
        #region Constructor & initialization
        //-----------------------------------------------------------------

        /// <summary>
        /// Default constructor
        /// </summary>
        internal CalendarViewModel()
        {
        }

        internal CalendarViewModel(SPSite pobjSite)
            : this()
        {
            if (pobjSite != null)
            {
                Model = new CalendarModel(pobjSite);
            }
        }

        //-----------------------------------------------------------------
        #endregion Constructor & initialization
        //-----------------------------------------------------------------


        //-----------------------------------------------------------------
        #region Logic
        //-----------------------------------------------------------------

        internal void FillTree(TreeView pobjTree)
        {
            if (pobjTree.Nodes.Count == 0)
            {
                if (Model != null)
                {
                    // Add RootWeb - everything will be added recursively
                    AddWebNode(pobjTree.Nodes, Model.RootWebData);
                }
            }
        }

        private TreeNode AddWebNode(TreeNodeCollection pobjNodes, CalendarWebData pobjWebData)
        {
            TreeNode result = null;
            //-----------------------------------------------------------------------

            try
            {
                result = new TreeNode(pobjWebData.Title, pobjWebData.ServerRelativeUrl, "/_layouts/images/cat.gif"); //calendar_grey
                result.NavigateUrl = string.Empty;
                pobjNodes.Add(result);
            }
            catch (Exception excCreateNode)
            {
                UlsLogger.Error("An error occurred while trying to add CalendarWebData TreeNode : " + excCreateNode.Message);
            }

            try
            {
                // SubWebs
                foreach (CalendarWebData subWebData in pobjWebData.WebsData)
                {
                    AddWebNode(result.ChildNodes, subWebData);
                }

                // Lists
                foreach (CalendarListData listData in pobjWebData.ListsData)
                {
                    AddListNode(result.ChildNodes, listData);
                }
            }
            catch(Exception excRecurse)
            {
                UlsLogger.Error("An error occurred while trying to add subNodes recursively : " + excRecurse.Message);
            }

            //-----------------------------------------------------------------------
            return result;
        }

        private void AddListNode(TreeNodeCollection pobjNodes, CalendarListData pobjListData)
        {
            try
            {
                TreeNode lobjListNode = new TreeNode(pobjListData.Title, pobjListData.ServerRelativeUrl, "/_layouts/images/calendar_grey.gif");
                lobjListNode.ShowCheckBox = true;
                lobjListNode.NavigateUrl = string.Empty;
                pobjNodes.Add(lobjListNode);
            }
            catch (Exception excRecurse)
            {
                UlsLogger.Error("An error occurred while trying to add subNodes recursively : " + excRecurse.Message);
            }
        }


        #region GET informations from View

        internal string GetCheckedListsUrl(TreeView pobjTree)
        {
            string result = string.Empty;
            //---------------------------------------------------------

            if (pobjTree.Nodes.Count > 0)
            {
                // start from the root node
                result = GetWebCheckedNodesValues(pobjTree.Nodes[0]);
            }

            //---------------------------------------------------------
            return result;
        }

        private string GetWebCheckedNodesValues(TreeNode pobjWebNode)
        {
            string result = string.Empty;
            //---------------------------------------------------------

            try
            {
                // fetch current lists nodes
                IEnumerable<string> listsUrls =
                    from TreeNode listNode in pobjWebNode.ChildNodes
                    where listNode.ShowCheckBox == true && listNode.Checked
                    select listNode.Value;

                // concat with ";" separator
                result = string.Join(";", listsUrls.ToArray());
            }
            catch (Exception excGetWebCheckedNodes)
            {
                UlsLogger.Error("An error occurred while trying to get Web checked TreeNodes : " + excGetWebCheckedNodes.Message);
            }


            // Recurse on sub web nodes
            try
            {
                IEnumerable<string> subWebsListsUrls =
                    from TreeNode webNode in pobjWebNode.ChildNodes
                    where !webNode.ShowCheckBox.HasValue || webNode.ShowCheckBox == false
                    select GetWebCheckedNodesValues(webNode);

                string lstrBuffer = string.Join(";", subWebsListsUrls.Where(url => !string.IsNullOrEmpty(url)).ToArray()).Trim();

                if(!string.IsNullOrEmpty(lstrBuffer))
                {
                    result += ";" + lstrBuffer;
                }
            }
            catch (Exception excRecurse)
            {
                UlsLogger.Error("An error occurred while trying to recurse on Web sub-TreeNodes : " + excRecurse.Message);
            }

            //---------------------------------------------------------
            return result;
        }

        #endregion GET informations from View


        #region SET informations to View

        internal void SetCheckedListsUrl(TreeView pobjTree, string listsUrls)
        {
            if (pobjTree.Nodes.Count > 0)
            {
                IEnumerable<string> arrUrls = 
                    listsUrls
                    .Split(';')
                    .Select(s => s.ToLower());

                SetWebCheckedNodes(pobjTree.Nodes[0], arrUrls);
            }
        }

        private void SetWebCheckedNodes(TreeNode pobjNode, IEnumerable<string> arrUrls)
        {
            try
            {
                // Check lists nodes to be checked
                foreach (TreeNode node in pobjNode.ChildNodes)
                {
                    try
                    {
                        if (node.ShowCheckBox == true)
                        {
                            if (arrUrls.Contains(node.Value.ToLower()))
                            {
                                node.Checked = true;
                            }
                        }
                    }
                    catch (Exception excCheckNode)
                    {
                        UlsLogger.Error("An error occurred while trying to check a TreeNode : " + excCheckNode.Message);
                    }
                }


                // Recurse
                foreach (TreeNode node in pobjNode.ChildNodes)
                {
                    try
                    {
                        if (!node.ShowCheckBox.HasValue || node.ShowCheckBox == false)
                        {
                            SetWebCheckedNodes(node, arrUrls);
                        }
                    }
                    catch (Exception excRecurse)
                    {
                        UlsLogger.Error("An error occurred while trying to recurse on checking TreeNodes : " + excRecurse.Message);
                    }
                }
            }
            catch (Exception excSetCheckedNode)
            {
                UlsLogger.Error("An error occurred while trying to set checled nodes : " + excSetCheckedNode.Message);
            }
        }

        #endregion SET informations to View

        //-----------------------------------------------------------------
        #endregion Logic
        //-----------------------------------------------------------------
    }
}
